package com.xlh.service.cs.impl;

import com.google.common.collect.Lists;
import com.xlh.dao.course.CourseBasicMapper;
import com.xlh.dao.cs.CourseSystemMapperExt;
import com.xlh.dto.course.CourseIndexInfoDTO;
import com.xlh.dto.cs.CourseListDTO;
import com.xlh.dto.cs.CourseSystemCourseDTO;
import com.xlh.dto.cs.CourseSystemTreeDTO;
import com.xlh.enums.course.CourseStatusEnum;
import com.xlh.enums.cs.CourseSystemTypeEnum;
import com.xlh.enums.cs.EditItemEnum;
import com.xlh.enums.cs.OperationTypeEnum;
import com.xlh.exception.common.GlobalException;
import com.xlh.param.cs.CourseSystemParam;
import com.xlh.param.cs.EditCourseSystemParam;
import com.xlh.pojo.course.CourseBasicExample;
import com.xlh.service.course.CourseService;
import com.xlh.service.cs.*;
import com.xlh.util.BeanUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhr 2019/10/17
 */
@Service
public class CourseSystemServiceImpl implements CourseSystemService {

    @Autowired
    private CourseSystemCourseService courseService;
    @Autowired
    private CourseService systemCourseService;
    @Autowired
    private CourseSystemLearningPhaseService learningPhaseService;
    @Autowired
    private CourseSystemWorkPlaceService workPlaceService;
    @Autowired
    private CoursePhaseService coursePhaseService;
    @Autowired
    private CourseWorkService courseWorkService;

    @Autowired
    private CourseSystemMapperExt mapperExt;
    @Autowired
    private CourseBasicMapper courseBasicMapper;

    @Override
    public void editCourseSystem(List<CourseSystemParam> paramList, EditItemEnum itemEnum) {
        // 重新设置排序字段,并将所有未修改项强制变为修改操作
        for (int i = 0; i < paramList.size(); i++) {
            CourseSystemParam param = paramList.get(i);
            param.setOrderNum(i);
            if (Objects.equals(OperationTypeEnum.NO_OPERATE.getType(), param.getOperation())) {
                param.setOperation(OperationTypeEnum.UPDATE.getType());
            }
        }

        // 验证列表是否存在重复名称
        checkNameDuplicate(paramList, itemEnum);

        List<CourseSystemParam> insertList = paramList.stream().filter(param -> Objects.equals(param.getOperation(), OperationTypeEnum.INSERT.getType())).collect(Collectors.toList());
        List<CourseSystemParam> updateList = paramList.stream().filter(param -> Objects.equals(param.getOperation(), OperationTypeEnum.UPDATE.getType())).collect(Collectors.toList());
        List<CourseSystemParam> deleteList = paramList.stream().filter(param -> Objects.equals(param.getOperation(), OperationTypeEnum.DELETE.getType())).collect(Collectors.toList());

        switch (itemEnum) {
            case COURSE:
                courseService.batchEdit(insertList, updateList, deleteList);
                break;
            case WORK_PLACE:
                workPlaceService.batchEdit(insertList, updateList, deleteList);
                break;
            case LEARNING_PHASE:
                learningPhaseService.batchEdit(insertList, updateList, deleteList);
                break;
            default:
        }
    }

    @Override
    public CourseListDTO listCourse() {
        // 查询系统课程
        List<CourseSystemCourseDTO> systemCourseList = courseService.listSystemCourse();
        // 查询非系统课程
        List<CourseSystemCourseDTO> notSystemCourseList = courseService.listNotSystemCourse();
        // 查询学习阶段-课程对应关系
        List<CourseSystemTreeDTO> phaseList = coursePhaseService.getCoursePhase(systemCourseList, notSystemCourseList);
        // 查询工作岗位-课程对应关系
        List<CourseSystemTreeDTO> workList = courseWorkService.getCourseWork(systemCourseList, notSystemCourseList);
        return new CourseListDTO(systemCourseList, notSystemCourseList, phaseList, workList);
    }

    @Override
    public void editCourseSystem(EditCourseSystemParam param) {
        // 编辑课程-学习阶段
        coursePhaseService.edit(param.getPhaseList());
        // 编辑课程-工作岗位
        courseWorkService.edit(param.getWorkList());
    }

    @Override
    public List<CourseSystemTreeDTO> showCourseSystem(Long workId, Long userId) {
        List<CourseSystemTreeDTO> list = mapperExt.selectList();

        // 获取系统课程对应课程id
        List<CourseIndexInfoDTO> courseIndexList = getIndexData();
        // 课程id转为basicId映射
        Map<Long, CourseIndexInfoDTO> courseIndexMap = BeanUtil.mapByKey("courseBasicId", courseIndexList);

        // 非系统课程映射
        List<CourseSystemCourseDTO> notSystemCourseList = courseService.listNotSystemCourse();
        Map<Long, CourseSystemCourseDTO> notSystemCourseMap = BeanUtil.mapByKey("id", notSystemCourseList);
        // 系统课程映射

        // 设置课程名称等内容
        if (CollectionUtils.isNotEmpty(list)) {
            list.forEach(courseSystemTreeDTO -> {
                List<CourseSystemCourseDTO> courseList = courseSystemTreeDTO.getCourseList();
                if (CollectionUtils.isNotEmpty(courseList)) {
                    courseList.forEach(courseDTO -> {
                        // 工作岗位id不为空时,对数据做高亮处理
                        courseDTO.setHasWork(workId != null && containWorkId(courseDTO.getWorkIdList(), workId));
                        if (Objects.equals(CourseSystemTypeEnum.SYSTEM_COURSE.getType(), courseDTO.getType())){
                            courseDTO.setName(courseIndexMap.get(courseDTO.getId()).getName());
                            courseDTO.setId(courseIndexMap.get(courseDTO.getId()).getId());
                        } else {
                            courseDTO.setName(notSystemCourseMap.get(courseDTO.getId()).getName());
                        }
                    });
                }
            });
        }
        return list;
    }

    private boolean containWorkId(List<Long> workIdList, Long workId) {
        if (CollectionUtils.isEmpty(workIdList)) {
            return false;
        }
        return workIdList.contains(workId);
    }

    private void checkNameDuplicate(List<CourseSystemParam> paramList, EditItemEnum itemEnum) {
        // 判断本列表中是否有重复数据
        List<CourseSystemParam> filterList = paramList.stream().filter(param -> !Objects.equals(param.getOperation(), OperationTypeEnum.DELETE.getType())).collect(Collectors.toList());
        Set<String> nameSet = filterList.stream().map(param -> StringUtils.trim(param.getName())).collect(Collectors.toSet());
        if (nameSet.size() < filterList.size()) {
            throw new GlobalException("不能添加重复名称");
        }

        // 判断名称中是否有与系统课程名称重复的课程
        if (Objects.equals(itemEnum, EditItemEnum.COURSE) && duplicateInCourseBasic(nameSet)) {
            throw new GlobalException("与系统课程名称重复");
        }
    }

    private boolean duplicateInCourseBasic(Set<String> nameSet) {
        if (CollectionUtils.isEmpty(nameSet)) {
            return false;
        }
        CourseBasicExample example = new CourseBasicExample();
        example.createCriteria().andNameIn(Lists.newArrayList(nameSet)).andDeletedEqualTo(false);
        return courseBasicMapper.countByExample(example) > 0;
    }

    private List<CourseIndexInfoDTO> getIndexData() {
        List<CourseIndexInfoDTO> courseIndexList = systemCourseService.getIndexData();
        if (CollectionUtils.isEmpty(courseIndexList)) {
            return Lists.newArrayList();
        }

        return courseIndexList.stream().filter(dto -> Objects.equals(CourseStatusEnum.SHARED.getCode(), dto.getStatus())).collect(Collectors.toList());
    }
}
